package user;

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.NoSuchAlgorithmException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;

import Email.SendEmail;
import Encryption.Encryptor;
import Hash.Hashing;

import security.servlet.SecurityServlet;

import db.PreparedQuery;

public class User {

	public static final String TABLE_NAME = "User";
	public static final String User_ID_FIELD_NAME = TABLE_NAME + ".UserID";
	public static final String PASSWORD_FIELD_NAME = TABLE_NAME + ".password";
	public static final String CC_FIELD_NAME = TABLE_NAME + ".creditcardnumber";
	public static final String EMAIL_FIELD_NAME = TABLE_NAME + ".email";
	public static final String NAME_FIELD_NAME = TABLE_NAME + ".name";
	public static final String TIME_STAMP = TABLE_NAME + ".timeStamp";
	
	public User() {
	}

	public User(String userName2, String creditCardNumber2) {
		this.userName = userName2;
		this.creditCardNumber = creditCardNumber2;
	}

	private int userId;
	private String userName;
	private String creditCardNumber;
	private String password;
	private String email;
	private long timeStamp;

	public boolean load() throws Exception {
		String sql = "SELECT " + PASSWORD_FIELD_NAME + "," + TIME_STAMP
				+ " FROM USER WHERE name =? ;";

		PreparedQuery q = new PreparedQuery();
		ResultSet rs = null;
		try {
			q.open(sql);
			q.setParameter(1, this.getUserName());

			rs = q.executeQuery();
			// System.out.println(rs.toString());
			if (rs.next()) {
				byte i = 1;
				this.password = rs.getString(i++);
				this.timeStamp = Long.parseLong(rs.getString(i++));
				return true;
			}
			return false;
		} finally {
			if (rs != null)
				rs.close();
			q.close();
		}
	}

	/*public boolean load() throws Exception {
		String sql = "SELECT " + PASSWORD_FIELD_NAME + "," + TIME_STAMP
				+ " FROM USER WHERE name = '"+userName +"'\n;";

		PreparedQuery q = new PreparedQuery();
		ResultSet rs = null;
		try {
			q.open(sql);
			//q.setParameter(1, this.getUserName());

			rs = q.executeQuery();
			// System.out.println(rs.toString());
			if (rs.next()) {
				byte i = 1;
				this.password = rs.getString(i++);
				this.timeStamp = Long.parseLong(rs.getString(i++));
				return true;
			}
			return false;
		} finally {
			if (rs != null)
				rs.close();
			q.close();
		}
	}
*/	public ArrayList<User> loadAllUsers(boolean flag, BigInteger key) throws Exception {
		ArrayList<User> allUsers = new ArrayList<User>();
		String sql = "SELECT " + NAME_FIELD_NAME + "," +CC_FIELD_NAME
				+ " FROM USER  ;";

		PreparedQuery q = new PreparedQuery();
		ResultSet rs = null;
		try {
			q.open(sql);
			rs = q.executeQuery();
			// System.out.println(rs.toString());
			while (rs.next()) {
				byte i = 1;
				this.userName = rs.getString(i++);
				if(!flag)
					this.creditCardNumber = rs.getString(i++);
				else{
					this.creditCardNumber = decrypt(rs.getString(i++),key);
				}
				allUsers.add(new User(this.userName,this.creditCardNumber));
			
			}
		
			return allUsers;
			
		} finally {
			if (rs != null)
				rs.close();
			q.close();
		}
	}
	public void getUserEmail() throws SQLException, ClassNotFoundException {
		String sql = "SELECT " + EMAIL_FIELD_NAME 
				+ " FROM USER WHERE name =? ;";

		PreparedQuery q = new PreparedQuery();
		ResultSet rs = null;
		try {
			q.open(sql);
			q.setParameter(1, this.getUserName());

			rs = q.executeQuery();
			// System.out.println(rs.toString());
			if (rs.next()) {
				byte i = 1;
				this.email = rs.getString(i++);
			}

		} finally {
			if (rs != null)
				rs.close();
			q.close();
		}
	}

	public boolean register() throws Exception {
		String sql = "INSERT INTO User set " + PASSWORD_FIELD_NAME + " = ?,"
				+ NAME_FIELD_NAME + " =?," + CC_FIELD_NAME + " =?,"
				+ EMAIL_FIELD_NAME + " =?, " + TIME_STAMP + " =?;";
		PreparedQuery q = new PreparedQuery();


			q.open(sql);

			long lDateTime = new Date().getTime();
			String timeStamp = lDateTime + "";
			byte[] timeStampb = timeStamp.getBytes("UTF-8");
			String password = Encryptor.b2h(Hashing.getHash(this.getPassword(),
					timeStampb));
			q.setParameter(1, password);
			q.setParameter(2, this.getUserName());
			String CreditCard = this.getCreditCardNumber();
			CreditCard = Encryptor.b2h(Encryptor.encryptWithPubKey(CreditCard.getBytes("UTF-8")));
			SecurityServlet.encrypted = CreditCard;

			// CreditCard = new String(CreditCard.getBytes("UTF-8"));
			System.out.println(CreditCard.length());
			q.setParameter(3, CreditCard);
			q.setParameter(4, this.getEmail());
			q.setParameter(5, lDateTime);
			q.executeUpdate();
			// System.out.println(rs.toString());
			q.close();
			return true;
		 
	}

	public String decrypt(String creditCard, BigInteger key) throws Exception {
		return new String(Encryptor
				.decryptWithPrivKey(Encryptor
						.h2b(creditCard),key), "UTF-8");
	}

	public void resetLink() throws UnsupportedEncodingException,
			NoSuchAlgorithmException, SQLException {
		long lDateTime = new Date().getTime();
		String timeStamp = lDateTime + "";
		byte[] timeStampb = timeStamp.getBytes("UTF-8");
		String resetKey = Encryptor.b2h(Hashing.getHash(this.getUserName(),
				timeStampb));
		String sql = "Insert into reset set Name =?," + "timeStamp =?,"
				+ "resetKey=?";
		PreparedQuery q = new PreparedQuery();
		try {

			q.open(sql);
			q.setParameter(1, this.getUserName());
			q.setParameter(2, lDateTime);
			q.setParameter(3, resetKey);
			q.executeUpdate();
			// System.out.println(rs.toString());

		} catch (Exception e) {
			System.out.println(e.getMessage());
			e.printStackTrace();
		} finally {
			q.close();
		}

	}

	public void updatePassword() throws UnsupportedEncodingException,
			SQLException, ClassNotFoundException, NoSuchAlgorithmException {
		String sql = "UPDATE User SET Password =?, " + "timeStamp=?"
				+ " where Name =?;";
		PreparedQuery q = new PreparedQuery();
		try {
			long lDateTime = new Date().getTime();
			String timeStamp = lDateTime + "";
			byte[] timeStampb = timeStamp.getBytes("UTF-8");
			q.open(sql);
			String password = Encryptor.b2h(Hashing.getHash(this.getPassword(),
					timeStampb));
			q.setParameter(1, password);
			q.setParameter(2, lDateTime);
			q.setParameter(3, this.userName);
			q.executeUpdate();
		} finally {
			q.close();
		}
	}

	public int getUserId() {
		return userId;
	}

	public void setUserId(int userId) {
		this.userId = userId;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getCreditCardNumber() {
		return creditCardNumber;
	}

	public void setCreditCardNumber(String creditCardNumber) {
		this.creditCardNumber = creditCardNumber;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public long getTimeStamp() {
		return timeStamp;
	}

	public void setTimeStamp(long timeStamp) {
		this.timeStamp = timeStamp;
	}

	/*
	 * public void update() throws Exception { String sql = "UPDATE " +
	 * TABLE_NAME + " SET " + sqlUpdate + " Where " + IMG_ID_FIELD_NAME + "=?";
	 * 
	 * PreparedQuery q = new PreparedQuery(); q.open(); try { q.prepare(sql);
	 * int i = setUpdateParameters(q); q.setParameter(i, getImageID());
	 * q.executeUpdate(); } finally { q.close(); } }
	 * 
	 * public void add() throws Exception { String sql = "INSERT INTO " +
	 * TABLE_NAME + " SET "+ sqlUpdate +";";
	 * 
	 * PreparedQuery q = new PreparedQuery(); q.open(); try { q.prepare(sql);
	 * setUpdateParameters(q); q.executeUpdate();
	 * q.prepare(Query.qryGetLastAdded); ResultSet rs = (ResultSet)
	 * q.executeQuery(); rs.next(); this.imageID = rs.getInt(1); rs.close(); }
	 * finally { q.close(); } }
	 * 
	 * private int setUpdateParameters(PreparedQuery q) throws Exception { byte
	 * i = 1; q.setParameter(i++, getExt_ImageID()); q.setParameter(i++,
	 * getUserID()); q.setParameter(i++, getArchived());
	 * 
	 * return i; }
	 */
}
